package by.dezhits.liltweets.service;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import by.dezhits.liltweets.R;
import by.dezhits.liltweets.api.TwitterAPI;
import by.dezhits.liltweets.content.contract.PostContract;
import by.dezhits.liltweets.content.contract.TweetContract;
import by.dezhits.liltweets.content.contract.UsersContract;
import by.dezhits.liltweets.db.DBHelper;
import by.dezhits.liltweets.http.HttpManager;
import by.dezhits.liltweets.http.HttpRequestBuilder;
import by.dezhits.liltweets.http.HttpRequestBuilder.TwitterRequest;
import by.dezhits.liltweets.http.HttpRequestBuilder.Type;
import by.dezhits.liltweets.task.JsonObjectTask;
import by.dezhits.liltweets.task.ListJsonObjectTask;
import by.dezhits.liltweets.task.ParamCallback;

/**
 * @author IstiN
 * 
 */
public class HttpService extends Service {

	private static final String THE_MESSAGE_CANNOT_BE_SENT_NOW = "The message cannot be sent right now. You can send it later from the draft";

	private static final String SUCH_TWEET_CANNOT_BE_SUBMITTED = "Such tweet cannot be submitted";

	private static final String NO_RESULTS = "No results";

	private static final String HOST_SENT_WRONG_USER_INFO = "Host sent wrong user info";

	public static final String EXTRA_KEY_MESSAGE = "message";

	public static final String ACTION_ON_ERROR_HOMEPAGE = "by.dezhits.liltweets.service.ACTION_ON_ERROR_HOMEPAGE";

	public static final String ACTION_ON_SUCCESS_HOMEPAGE = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_HOMEPAGE";

	public static final String ACTION_ON_ERROR_USERPAGE = "by.dezhits.liltweets.service.ACTION_ON_ERROR_USERPAGE";

	public static final String ACTION_ON_SUCCESS_USERPAGE = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_USERPAGE";

	public static final String ACTION_ON_ERROR_POSTTWEET = "by.dezhits.liltweets.service.ACTION_ON_ERROR_POSTTWEET";

	public static final String ACTION_ON_SUCCESS_POSTTWEET = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_POSTTWEET";

	public static final String ACTION_ON_ERROR_RETWEET = "by.dezhits.liltweets.service.ACTION_ON_ERROR_RETWEET";

	public static final String ACTION_ON_SUCCESS_RETWEET = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_RETWEET";

	public static final String ACTION_ON_ERROR_DESTROY = "by.dezhits.liltweets.service.ACTION_ON_ERROR_DESTROY";

	public static final String ACTION_ON_SUCCESS_DESTROY = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_DESTROY";

	public static final String ACTION_ON_SUCCESS_SEARCH = "by.dezhits.liltweets.service.ACTION_ON_SUCCESS_SEARCH";

	public static final String ACTION_ON_ERROR_SEARCH = "by.dezhits.liltweets.service.ACTION_ON_ERROR_SEARCH";

	public static final String HTTP_REQUEST_BUILDER = "http_request_builder";

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		handleCommand(intent);
		// We want this service to continue running until it is explicitly
		// stopped, so return sticky.
		return START_STICKY;
	}

	protected void handleCommand(Intent intent) {
		if (intent == null) {
			return;
		}
		final HttpRequestBuilder httpRequestBuilder = (HttpRequestBuilder) intent
				.getSerializableExtra(HTTP_REQUEST_BUILDER);
		if (httpRequestBuilder == null) {
			return;
		}

		if (httpRequestBuilder.getType() == Type.GET) {
			if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.STATUSES_HOME_TIMELINE) {
				new ListJsonObjectTask(new ParamCallback<List<JSONObject>>() {
					@Override
					public void onSuccess(final List<JSONObject> p) {
						Intent intent = new Intent(ACTION_ON_SUCCESS_HOMEPAGE);
						sendBroadcast(intent);
						if (p != null) {
							new Thread(new Runnable() {
								final int tweetCount = p.size();

								@Override
								public void run() {

									int tweetIndex = 0;
									for (JSONObject jsonObject : p) {
										ContentValues contentValues = new ContentValues();
										contentValues.put(getString(R.string.data),
												jsonObject.toString());
										contentValues.put(getString(R.string.tweet_index),
												tweetIndex);
										contentValues.put(getString(R.string.tweet_count),
												tweetCount);
										getContentResolver()
												.insert(TweetContract.TweetsColumns.CONTENT_URI,
														contentValues);
										tweetIndex++;
									}
								}

							}).start();

						}
					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_HOMEPAGE);
						intent.putExtra(EXTRA_KEY_MESSAGE, e.getMessage());
						sendBroadcast(intent);
					}
				}, HttpManager.GET).start(httpRequestBuilder.getUrl());
			} else if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.USERS_SHOW) {
				new JsonObjectTask(new ParamCallback<JSONObject>() {
					@Override
					public void onSuccess(final JSONObject p) {
						ContentValues contentValues = new ContentValues();
						contentValues.put(getString(R.string.data), p.toString());
						Uri uri = getContentResolver().insert(
								UsersContract.UsersColumns.CONTENT_URI,
								contentValues);
						long id = Integer.parseInt(uri.getLastPathSegment());
						Intent intent;
						if (id != -1) {
							intent = new Intent(ACTION_ON_SUCCESS_USERPAGE);
							intent.putExtra(getString(R.string.id), String.valueOf(id));
							sendBroadcast(intent);
						}
						else{
							intent = new Intent(ACTION_ON_ERROR_USERPAGE);
							intent.putExtra(EXTRA_KEY_MESSAGE, HOST_SENT_WRONG_USER_INFO);
							sendBroadcast(intent);
						}
					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_USERPAGE);
						intent.putExtra(EXTRA_KEY_MESSAGE, e.getMessage());
						sendBroadcast(intent);
					}

				}, HttpManager.GET).start(httpRequestBuilder.getUrl());
			} else if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.SEARCH_TWEETS) {
				new JsonObjectTask(new ParamCallback<JSONObject>() {
					@Override
					public void onSuccess(final JSONObject p) {
						try {
							JSONArray statuses = p.getJSONArray("statuses");
							if (statuses == null) {
								throw new JSONException("");
							}
							if (statuses.length() < 1) {
								throw new JSONException("");

							}
							for (int i = 0; i < statuses.length(); i++) {
								ContentValues contentValues = new ContentValues();
								contentValues.put(getString(R.string.data), statuses
										.getJSONObject(i).toString());
								getContentResolver()
										.insert(TweetContract.TweetsColumns.SEARCH_RESULT_URI,
												contentValues);
							}
							Intent intent = new Intent(ACTION_ON_SUCCESS_SEARCH);
							sendBroadcast(intent);
						} catch (JSONException e) {
							Intent intent = new Intent(ACTION_ON_ERROR_SEARCH);
							intent.putExtra(EXTRA_KEY_MESSAGE, NO_RESULTS);
							sendBroadcast(intent);
						}

					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_SEARCH);
						intent.putExtra(EXTRA_KEY_MESSAGE, e.getMessage());
						sendBroadcast(intent);
					}

				}, HttpManager.GET).start(httpRequestBuilder.getUrl());

			}
		} else if (httpRequestBuilder.getType() == Type.POST) {
			if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.STATUSES_UPDATE) {
				new JsonObjectTask(new ParamCallback<JSONObject>() {
					@Override
					public void onSuccess(final JSONObject p) {
						Intent intent = new Intent(ACTION_ON_SUCCESS_POSTTWEET);
						String s = "";
						try {
							s = p.getString("text");
						} catch (Exception e) {
							// Ignoreed because already initialized
						}
						final String text = s;
						sendBroadcast(intent);
						if (p != null) {
							new Thread(new Runnable() {
								@Override
								public void run() {
									ContentValues contentValues = new ContentValues();
									contentValues.put(getString(R.string.data), p.toString());
									contentValues.put(getString(R.string.tweet_index), 0);
									contentValues.put(getString(R.string.tweet_count), 1);
									getContentResolver()
											.insert(TweetContract.TweetsColumns.CONTENT_URI,
													contentValues);
								}
							}).start();
							new Thread(new Runnable() {
								@Override
								public void run() {
									ContentValues contentValues = new ContentValues();
									contentValues.put(getString(R.string.text), text);
									contentValues.put(getString(R.string.status),
											DBHelper.PostFlags.SENT);
									getContentResolver()
											.insert(PostContract.PostColumns.CONTENT_URI,
													contentValues);
								}
							}).start();
						}
					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_POSTTWEET);
						String s = DBHelper.PostFlags.NOT_SENT;
						if (e.getMessage().equals(TwitterAPI.Error.FORBIDDEN)) {
							s = DBHelper.PostFlags.CANNOT_BE_SENT;
							intent.putExtra(EXTRA_KEY_MESSAGE,
									SUCH_TWEET_CANNOT_BE_SUBMITTED);
						} else {
							intent.putExtra(EXTRA_KEY_MESSAGE,
									THE_MESSAGE_CANNOT_BE_SENT_NOW);
						}
						sendBroadcast(intent);
						Uri uri = Uri.parse(httpRequestBuilder.getUrl());
						final String text = uri.getQueryParameter(getString(R.string.status));
						final String status = s;
						new Thread(new Runnable() {
							@Override
							public void run() {
								ContentValues contentValues = new ContentValues();
								contentValues.put(getString(R.string.text), text);
								contentValues.put(getString(R.string.status), status);
								getContentResolver().insert(
										PostContract.PostColumns.CONTENT_URI,
										contentValues);
							}
						}).start();
					}

				}, HttpManager.POST).start(httpRequestBuilder.getUrl());
			}

			else if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.STATUSES_RETWEET) {
				new JsonObjectTask(new ParamCallback<JSONObject>() {

					@Override
					public void onSuccess(final JSONObject p) {
						Intent intent = new Intent(ACTION_ON_SUCCESS_RETWEET);
						sendBroadcast(intent);
						if (p != null) {
							new Thread(new Runnable() {
								@Override
								public void run() {
									ContentValues contentValues = new ContentValues();
									contentValues.put(getString(R.string.data), p.toString());
									contentValues.put(getString(R.string.tweet_index), 0);
									contentValues.put(getString(R.string.tweet_count), 1);
									getContentResolver()
											.insert(TweetContract.TweetsColumns.CONTENT_URI,
													contentValues);
								}
							}).start();
						}

					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_RETWEET);
						intent.putExtra(EXTRA_KEY_MESSAGE, e.getMessage());
						sendBroadcast(intent);
					}

				}, HttpManager.POST).start(httpRequestBuilder.getUrl());
			}

			else if (httpRequestBuilder.getTwitterRequest() == TwitterRequest.STATUSES_DESTROY) {
				new JsonObjectTask(new ParamCallback<JSONObject>() {

					@Override
					public void onSuccess(final JSONObject p) {
						Intent intent = new Intent(ACTION_ON_SUCCESS_DESTROY);
						sendBroadcast(intent);
						if (p != null) {
							new Thread(new Runnable() {
								@Override
								public void run() {
									try {
										getContentResolver()
												.delete(TweetContract.TweetsColumns.CONTENT_URI,
														TweetContract.TweetsColumns.ID
																+ "="
																+ String.valueOf(p
																		.getString("id")),
														null);
									} catch (JSONException e) {
									}

								}
							}).start();
						}

					}

					@Override
					public void onError(Throwable e) {
						Intent intent = new Intent(ACTION_ON_ERROR_DESTROY);
						intent.putExtra(EXTRA_KEY_MESSAGE, e.getMessage());
						sendBroadcast(intent);
					}

				}, HttpManager.POST).start(httpRequestBuilder.getUrl());
			}

		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

}